﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Base
{
    //自定义委托，委托是一种特殊的类。可以在命名空间中定义，也可以在类中定义，作为嵌套类。可以使用类名.委托类 变量名= new 类名.委托类（）调用
    public delegate int Calc(int a, int b);

    //class DelegateDemo1
    //{
    //    static void Main(string[] args)
    //    {
    //        //委托就是函数指针 
    //        Calculate c = new Calculate();

    //        //Action和Func是C#为我们准备好的委托
    //        //Action委托接收返回值为void的方法
    //        Action action = new Action(c.Report);
    //        c.Report();
    //        action.Invoke();
    //        action();

    //        //Func委托接收有返回值的方法
    //        Func<int, int, int> func1 = new Func<int, int, int>(c.Add);
    //        Func<int, int, int> func2 = new Func<int, int, int>(c.Sub);
    //        Console.WriteLine(func1.Invoke(3, 2));
    //        Console.WriteLine(func2.Invoke(3, 2));
    //        Console.WriteLine(func1(3, 2));
    //        Console.WriteLine(func2(3, 2));

    //        //使用自定义委托
    //        Calc calc1 = new Calc(c.Add);
    //        Calc calc2 = new Calc(c.Sub);
    //        Console.WriteLine(calc1.Invoke(3, 2));
    //        Console.WriteLine(calc2.Invoke(3, 2));
    //        Console.WriteLine(calc1(3, 2));
    //        Console.WriteLine(calc2(3, 2));

    //        //委托的一般使用 
    //        //1.模板方法，借用getProduct外部方法产生结果 //2.回调方法 根据要求调用logger
    //        WrapFactory wrapFactory = new WrapFactory();
    //        ProductFactory productFactory = new ProductFactory();
    //        Func<Product> f1 = new Func<Product>(productFactory.MakePizza);
    //        Func<Product> f2 = new Func<Product>(productFactory.MakeToyCar);

    //        Logger l = new Logger();
    //        Action<Product> log = new Action<Product>(l.Log);

    //        Box box1 = wrapFactory.Wrap(f1, log);
    //        Box box2 = wrapFactory.Wrap(f2, log);

    //        Console.WriteLine(box1.product.Name);
    //        Console.WriteLine(box2.product.Name);        
    //    }
    //}

    //计算类
    class Calculate
    {
        public void Report()
        {
            Console.WriteLine("thsi is calculate");
        }

        public int Add(int a, int b)
        {
            return a + b;
        }
        public int Sub(int a, int b)
        {
            return a - b;
        }
    }

    //log类
    class Logger
    {
        public void Log(Product product)
        {
            Console.WriteLine("Product '{0}' ,create at {1} ,price = {2}",product.Name,DateTime.Now,product.Price);
        }
    }

    //产品类
    class Product
    {
        public string Name { get; set; }
        public int Price { get; set; }
    }

    //盒子类
    class Box
    {
        public Product product { get; set; }
    }

    //包装工厂类
    class WrapFactory
    {
        public Box Wrap(Func<Product> getProduct,Action<Product> logger)
        {
            Box box = new Box();
            Product product = getProduct.Invoke();
            if (product.Price >= 50)
            {
                logger.Invoke(product);
            }
            box.product = product;
            return box;
        }
    }

    //产品工厂类
    class ProductFactory
    {
        public Product MakePizza()
        {
            Product product = new Product();
            product.Name = "Pizza";
            product.Price = 15;
            return product;
        }

        public Product MakeToyCar()
        {
            Product product = new Product();
            product.Name = "ToyCar";
            product.Price = 80;
            return product;
        }
    }
}
     